/* Autore: Nicola Agosti */
/*
Sia dato un insieme di nomi e cognomi di persone. Si scriva un programma in linguaggio C
che raggruppi le persone con ugual cognome, stampando di seguito tutti i nomi delle
persone che hanno lo stesso cognome.
I nomi ed i cognomi devono essere letti da tastiera, come nell’esempio, finché non viene 
letto il nome FINE LISTA.
L’ordine con cui si stampano i nomi ed i cognomi non è importante.

VINCOLI:
- Le persone hanno un solo nome e un solo cognome;
- Prima deve essere inserito il cognome e poi il nome;
- Il numero massimo di persone inseribili è 100;
- La lunghezza massima del nome e del cognome è rispettivamente di 20 caratteri. 

Esempio:

Introduci cognome e nome: Rossi Mario
Introduci cognome e nome: Verdi Giuseppe
Introduci cognome e nome: Rossi Paolo
Introduci cognome e nome: Bianchi Paolo
Introduci cognome e nome: Verdi Antonio
Introduci cognome e nome: Neri Luca
Introduci cognome e nome: Verdi Paolo
Introduci cognome e nome: Neri Giuseppe
Introduci cognome e nome: FINE LISTA

Le persone di cognome Rossi sono: Mario, Paolo
Le persone di cognome Verdi sono: Giuseppe, Antonio, Paolo
Le persone di cognome Bianchi sono: Paolo
Le persone di cognome Neri sono: Luca, Giuseppe
*/

#define _CRT_SECURE_NO_WARNINGS /* Necessario se utilizziamo Visual Studio */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_PERSONE 100
#define MAX_LUNG_NOME_COGNOME 20

#define VERO 1
#define FALSO 0

int main()
{
	/*
	Un vettore di stringhe non è altro che un vettotre bidimensionale (matrice) 
	dove ogni riga corrisponde a una stringa.
	*/
	char elencoPersone[100][2 * MAX_LUNG_NOME_COGNOME + 1];
	
	char tmp[2 * MAX_LUNG_NOME_COGNOME + 1];
	char nome[MAX_LUNG_NOME_COGNOME + 1], cognome[MAX_LUNG_NOME_COGNOME + 1], cognomePrecedente[MAX_LUNG_NOME_COGNOME + 1];
	int numPersoneInserite, i, j, almenoUnoScambio;

	/* Chiedo all'utente di inserire le persone */
	numPersoneInserite = 0;
	while(numPersoneInserite < MAX_PERSONE)
	{
		/* Leggo i dati della persona e li inserisco in "elencoPersone" */
		printf("Introduci cognome e nome (scrivi \"FINE LISTA\" per terminare): ");
		fgets(elencoPersone[numPersoneInserite], 2 * MAX_LUNG_NOME_COGNOME + 1, stdin);

		/* Controllo se l'utente ha inserito la stringa "FINE LISTA" */
		if (strcmp(elencoPersone[numPersoneInserite], "FINE LISTA\n") == 0)
		{
			/* Termino l'inserimento */
			break;
		}
		else
		{
			/* Aggiorno il numero di persone inserite */
			numPersoneInserite++;
		}
	}

	/* Controllo quante persone sono state inserite */
	if (numPersoneInserite >= 2)
	{
		/*** Ordino il vettore, utilizzando il BUBBLE SORT, in modo che tutti i cognomi uguali siano "vicini" ***/
	
		/* Sono necessari "numPersoneInserite" - 1 passi per garantire l'ordinamento dell'intero vettore */
		for (i = 0; i < numPersoneInserite - 1; i++)
		{
			/* Confronto gli elementi del vettore a coppie
			e se non sono in ordine crescente li scambio */
			almenoUnoScambio = FALSO;
			for (j = 0; j < numPersoneInserite - 1 - i; j++)
			{
				/* Verifico se l'elemento in posizione "j" è successivo in ordine alfabetico 
				a quello in posizione "j + 1", se sì li scambio perchè sono in posizione errata */
				if (strcmp(elencoPersone[j], elencoPersone[j + 1]) > 0)
				{
					/* Effettuo lo scambio utilizzando una variabile di appoggio */
					strcpy(tmp, elencoPersone[j]);
					strcpy(elencoPersone[j], elencoPersone[j + 1]);
					strcpy(elencoPersone[j + 1], tmp);

					almenoUnoScambio = VERO;
				}
			}

			/* Se non ho effettuato alcun scambio il vettore è già ordinato */
			if (almenoUnoScambio == FALSO)
			{
				break;
			}
		}

		/*** Scorro "elencoPersone" e "raggruppo" le persone con lo stesso cognome ***/
		
		/* Inizializzo la stringa "cognomePrecedente" */
		strcpy(cognomePrecedente, "");

		/* Scorro "elencoPersone" */
		for (i = 0; i < numPersoneInserite; i++)
		{
			/* Separo il cognome dal nome */
			sscanf(elencoPersone[i], "%s%s", cognome, nome);

			/* Controllo se "cognome" è diverso a "cognomePrecedente" */
			if (strcmp(cognome, cognomePrecedente) != 0)
			{
				/* Ho trovato un nuovo cognome */
				
				/* Creo una nuova riga in output */
				printf("\nLe persone di cognome %s sono: %s", cognome, nome);

				/* Copio "cognome" in "cognomePrecedente" */
				strcpy(cognomePrecedente, cognome);
			}
			else
			{
				/* Il cognome è uguale al precedente */

				/* Aggiungo il nome alla lista dei nomi associati a questo cognome */
				printf(", %s", nome);
			}
		}
	}
	else
	{
		if (numPersoneInserite == 1)
		{
			printf("\nSolo una persona inserita: %s", elencoPersone[0]);
		}
		else
		{
			printf("\nNessuna persona inserita!");
		}
	}
	
	return 0;
}